package com.gigi.service.manual;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gigi.entity.*;
import com.gigi.enums.ErrorCodeEnum;
import com.gigi.mapper.generated.BlogShiqinMapper;
import com.gigi.mapper.manual.BlogManualMapper;
import com.gigi.model.BlogDO;
import com.gigi.model.ListBlogRequest;
import com.gigi.service.generated.*;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class BlogManageService {

    private final BlogShiqinService blogShiqinService;
    private final TagShiqinService tagShiqinService;
    private final BlogShiqinMapper blogShiqinMapper;
    private final UserShiqinService userShiqinService;
    private final TypeShiqinService typeShiqinService;
    private final BlogManualMapper blogManualMapper;
    private final CollectShiqinService collectShiqinService;
    private final LikeShiqinService likeShiqinService;

    public BlogManageService(BlogShiqinService blogShiqinService, TagShiqinService tagShiqinService, BlogShiqinMapper blogShiqinMapper,
                             UserShiqinService userShiqinService, TypeShiqinService typeShiqinService, BlogManualMapper blogManualMapper,
                             CollectShiqinService collectShiqinService, LikeShiqinService likeShiqinService) {
        this.blogShiqinService = blogShiqinService;
        this.tagShiqinService = tagShiqinService;
        this.blogShiqinMapper = blogShiqinMapper;
        this.userShiqinService = userShiqinService;
        this.typeShiqinService = typeShiqinService;
        this.blogManualMapper = blogManualMapper;
        this.collectShiqinService = collectShiqinService;
        this.likeShiqinService = likeShiqinService;
    }

    /**
     * 保存接口
     *
     * @param request
     * @return
     */
    public Response save(BlogDO request) {
        // 如果没有传入id，则创建新实体
        if (ObjectUtil.isNull(request.getId())) {
            BlogShiqinEntity target = buildTarget(request);
            // 判断是否保存成功
            if (!blogShiqinService.save(target)) {
                return Response.buildFailure(ErrorCodeEnum.SAVE_FAILED.getErrCode(), ErrorCodeEnum.SAVE_FAILED.getErrDesc());
            }
        } else {
            // 根据id获取实体
            BlogShiqinEntity entity = blogShiqinService.getById(request.getId());
            // 判断是否获取成功
            if (Objects.isNull(entity)) {
                return SingleResponse.buildFailure(ErrorCodeEnum.NO_DATA.getErrCode(), ErrorCodeEnum.NO_DATA.getErrDesc());
            }
            // 构建更新实体
            BlogShiqinEntity target = buildTarget(request);
            target.setId(entity.getId());
            // 判断是否更新成功
            if (!blogShiqinService.updateById(target)) {
                return Response.buildFailure(ErrorCodeEnum.EDIT_FAILED.getErrCode(), ErrorCodeEnum.EDIT_FAILED.getErrDesc());
            }
        }
        // 判断是否保存成功
        return Response.buildSuccess();
    }

    private BlogShiqinEntity buildTarget(BlogDO request) {
        BlogShiqinEntity target = new BlogShiqinEntity();
        target.setTitle(request.getTitle());
        target.setContentValue(request.getContentValue());
        target.setContentHtml(request.getContentHtml());
        target.setTypeId(request.getTypeId());
        target.setTagId(StrUtil.join(StrUtil.COMMA, request.getTagId()));
        target.setPic(request.getPic());
        target.setZhaiyao(request.getZhaiYao());
        target.setUserId(request.getUserId());
        target.setTime(LocalDate.now());
        return target;
    }

    /**
     * 作品列表&搜索接口
     *
     * @param request
     * @return
     */
    public MultiResponse<BlogDO> list(ListBlogRequest request) {
        if (request.getPageNum() < 1) {
            request.setPageNum(1);
        }
        if (request.getPageSize() < 1) {
            request.setPageSize(10);
        }

        int startIndex = (request.getPageNum() - 1) * request.getPageSize();
        Long typeId = getTypeIdByName(request.getKeyWord());
        Long tagId = getTagIdByName(request.getKeyWord());

        List<BlogDO> list = blogManualMapper.list(typeId, tagId, request.getUserId(), request.getKeyWord(), startIndex,
                request.getPageSize());

        if (CollUtil.isEmpty(list)) {
            return MultiResponse.of(Collections.emptyList(), 0);
        }
        setDOs(list);
        return MultiResponse.of(list, blogManualMapper.listCount(typeId, tagId, request.getUserId(), request.getKeyWord()));
    }

    public void setDOs(List<BlogDO> list) {
        list.forEach(e -> {

            LambdaQueryWrapper<CollectShiqinEntity> wrapper = new LambdaQueryWrapper<CollectShiqinEntity>()
                    .eq(CollectShiqinEntity::getBlogId, e.getId());

            List<String> tagNames = getTagNames(e.getTagNamesStr());
            e.setTime(e.getTimeDate().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
            e.setTagId(tagNames);
            e.setTagNamesStr(StrUtil.join(StrUtil.COMMA, tagNames));
            e.setTypeName(typeShiqinService.getById(e.getTypeId()).getName());
            e.setUserName(userShiqinService.getById(e.getUserId()).getName());
            e.setCollectCount(collectShiqinService.count(wrapper));
        });
    }

    // 根据keyword获取分类id
    private Long getTypeIdByName(String keyWord) {
        Long typeId = null;
        if (StrUtil.isBlank(keyWord)) {
            return typeId;
        }
        LambdaQueryWrapper<TypeShiqinEntity> wrapper = new LambdaQueryWrapper<TypeShiqinEntity>()
                .eq(TypeShiqinEntity::getName, keyWord);
        TypeShiqinEntity typeEntity = typeShiqinService.getOne(wrapper, false);
        if (Objects.nonNull(typeEntity)) {
            typeId = typeEntity.getId();
        }
        return typeId;
    }

    // 根据keyword获取标签id
    private Long getTagIdByName(String keyWord) {
        Long tagId = null;
        if (StrUtil.isBlank(keyWord)) {
            return tagId;
        }
        LambdaQueryWrapper<TagShiqinEntity> wrapper = new LambdaQueryWrapper<TagShiqinEntity>()
                .eq(TagShiqinEntity::getName, keyWord);
        TagShiqinEntity tagEntity = tagShiqinService.getOne(wrapper, false);
        if (Objects.nonNull(tagEntity)) {
            tagId = tagEntity.getId();
        }
        return tagId;
    }

    // tagIds 转 tagNames
    public List<String> getTagNames(String tagId) {
        return StrUtil.split(tagId, StrUtil.COMMA).stream().map(e -> tagShiqinService.getById(Long.valueOf(e)).getName())
                .collect(Collectors.toList());
    }

    /**
     * 删除接口
     *
     * @param id
     * @return
     */
    public Response delete(Long id) {
        if (!blogShiqinService.removeById(id)) {
            return Response.buildFailure(ErrorCodeEnum.DELETE_FAILED.getErrCode(), ErrorCodeEnum.DELETE_FAILED.getErrDesc());
        }
        return Response.buildSuccess();
    }

    /**
     * 详情接口
     *
     * @param id
     * @return
     */
    public SingleResponse<BlogDO> detail(Long id) {
        BlogShiqinEntity entity = blogShiqinService.getById(id);
        if (Objects.isNull(entity)) {
            return SingleResponse.buildFailure(ErrorCodeEnum.NO_DATA.getErrCode(), ErrorCodeEnum.NO_DATA.getErrDesc());
        }

        LambdaQueryWrapper<CollectShiqinEntity> collectWrapper = new LambdaQueryWrapper<CollectShiqinEntity>()
                .eq(CollectShiqinEntity::getBlogId, entity.getId());

        LambdaQueryWrapper<LikeShiqinEntity> likeWrapper = new LambdaQueryWrapper<LikeShiqinEntity>()
                .eq(LikeShiqinEntity::getBlogId, entity.getId());

        TypeShiqinEntity typeEntity = typeShiqinService.getById(entity.getTypeId());
        UserShiqinEntity user = userShiqinService.getById(entity.getUserId());
        BlogDO blogDO = new BlogDO();
        blogDO.setId(entity.getId());
        blogDO.setTitle(entity.getTitle());
        blogDO.setContentValue(entity.getContentValue());
        blogDO.setTypeId(entity.getTypeId());
        blogDO.setTagId(StrUtil.split(entity.getTagId(), StrUtil.COMMA));
        blogDO.setPic(entity.getPic());
        blogDO.setZhaiYao(entity.getZhaiyao());
        blogDO.setUserId(entity.getUserId());
        blogDO.setTime(entity.getTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
        blogDO.setContentHtml(entity.getContentHtml());
        if (Objects.nonNull(user)) {
            blogDO.setUserName(user.getName());
            blogDO.setUserPic(user.getPic());
        }
        if (Objects.nonNull(typeEntity)) {
            blogDO.setTypeName(typeEntity.getName());
        }
        blogDO.setTagName(getTagNames(entity.getTagId()));
        blogDO.setLikeCount(likeShiqinService.count(likeWrapper));
        blogDO.setCollectCount(collectShiqinService.count(collectWrapper));
        return SingleResponse.of(blogDO);
    }

    /**
     * 热榜接口
     *
     * @return
     */
    public MultiResponse<BlogDO> hot5() {
        return MultiResponse.ofWithoutTotal(blogManualMapper.hot5());
    }

    /**
     * 推荐接口
     *
     * @return
     */
    public MultiResponse<BlogDO> recommend(ListBlogRequest request) {
        if (request.getPageNum() < 1) {
            request.setPageNum(1);
        }
        if (request.getPageSize() < 1) {
            request.setPageSize(10);
        }

        int startIndex = (request.getPageNum() - 1) * request.getPageSize();

        List<String> tagId = null;
        UserShiqinEntity user = userShiqinService.getById(request.getUserId());
        if (Objects.nonNull(user) && StrUtil.isNotBlank(user.getTagId())) {
            tagId = StrUtil.split(user.getTagId(), StrUtil.COMMA);
        }

        List<BlogDO> recommend = blogManualMapper.recommend(request.getTypeId(), tagId, startIndex, request.getPageSize());
        if (CollUtil.isEmpty(recommend)) {
            return MultiResponse.of(Collections.emptyList(), 0);
        }
        setDOs(recommend);
        return MultiResponse.of(recommend, blogManualMapper.recommendCount(request.getTypeId(), tagId));
    }

}
